<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
    <title>早春图</title>
    <style>
    html, body {
        margin: 0;
        height: 100%;
    }
    #c {
        width: 100%;
        height: 100%;
        display: block;
    }
    </style>
  </head>
  <body>
    <canvas id="c" data-engine="three.js r162" style="touch-action: none;" width="944" height="691"></canvas>
  
<script type="importmap">
{
  "imports": {
    "three": "./node_modules/three/build/three.module.js",
    "three/addons/": "./node_modules/three/examples/jsm/"
  }
}
</script>

<script type="module">
import * as THREE from './node_modules/three/build/three.module.js';
import { OrbitControls } from './node_modules/three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from './node_modules/three/examples/jsm/loaders/GLTFLoader.js';
import { GUI } from './node_modules/three/examples/jsm/libs/lil-gui.module.min.js';
import TWEEN from '../tween.esm.js';
function main() {

	const canvas = document.querySelector( '#c' );
	const renderer = new THREE.WebGLRenderer( { antialias: true, canvas } );
	renderer.toneMappingExposure = 1.5; // 默认值是1，增加数值可以增亮场景
	renderer.gammaOutput = true;
	renderer.gammaFactor = 2.2; // 典型的Gamma值

	

	const fov = 45;
	const aspect = 2; // the canvas default
	const near = 0.1;
	const far = 100;
	const cameras=[];
	cameras.push(new THREE.PerspectiveCamera( fov, aspect, near, far ));
	cameras[0].position.set( 0, 10, 20 );
	//渲染器和相机
		const width = window.innerWidth;
		const height = window.innerHeight;
		const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
		camera.position.set(3, 1, 8);
	
		
		//解决加载gltf格式模型颜色偏差问题
		renderer.outputEncoding = THREE.sRGBEncoding;
		// 相机移动
		new TWEEN.Tween({
			// 相机开始坐标
			y: camera.position.y,
			z: camera.position.z,
		})
			.to({
				// 相机结束坐标
				y: 2,
				z: 0,
			}, 10000)
			.onUpdate(function (obj) {
				// 动态改变相机位置
				camera.position.setY(obj.y);
				camera.position.setZ(obj.z);

			})
			.onComplete(function (obj) {
				controls= new OrbitControls(camera, renderer.domElement)
				//controls.enabled = true;
				// controls.enableDamping = true; // 启用阻尼（惯性效果), 这将给控制器带来过渡效果
				// controls.dampingFactor = 0.25; // 阻尼系数
				
				controls.target.set(0, 0, 0);
				controls.update();

			})
			.start();


		//路径
		var curve = new THREE.CatmullRomCurve3([

			new THREE.Vector3(3, 1, 8),

			new THREE.Vector3(0, 1, 8),

			new THREE.Vector3(-1, 1, 8),
			new THREE.Vector3(-1,1,2),
			new THREE.Vector3(-1, 2,1),
			new THREE.Vector3(1, 2,2),
			new THREE.Vector3(3, 1, 8),
			
		]);
		// 从曲线上获得501个顶点，数量根据需要自己设置
		var points = curve.getPoints(1000);


	const controls = new OrbitControls( cameras[0], canvas );
	controls.target.set( 0, 5, 0 );
	controls.update();
	
	const scene = new THREE.Scene();
	scene.background = new THREE.Color( 'black' );
	let mixer= new THREE.AnimationMixer(scene);
	const clock = new THREE.Clock();
	
	{

		const skyColor = 0xB1E1FF; // light blue
		const groundColor = 0xB97A20; // brownish orange
		const intensity = 2;
		const light = new THREE.HemisphereLight( skyColor, groundColor, intensity );
		scene.add( light );

	}
	{
		const ambientLight = new THREE.AmbientLight(0x3a2414, 8.97);
		scene.add(ambientLight);
		// 存储环境光相关参数的对象
		const lightParams = {
		intensity: ambientLight.intensity,
		color: ambientLight.color.getHex(),
		// 分解光源的RGB颜色分量
		r: (ambientLight.color.r * 255),
		g: (ambientLight.color.g * 255),
		b: (ambientLight.color.b * 255)
		};

		// 创建dat.GUI实例
		const gui = new GUI();

		// 添加亮度调整控制器
		gui.add(lightParams, 'intensity', 0, 30).name('Intensity').onChange(value => {
		ambientLight.intensity = value;
		});

		// 为R、G、B各创建一个控制器
		gui.add(lightParams, 'r', 0, 255).name('Red').onChange(updateColor);
		gui.add(lightParams, 'g', 0, 255).name('Green').onChange(updateColor);
		gui.add(lightParams, 'b', 0, 255).name('Blue').onChange(updateColor);

		// 定义更新颜色的函数
		function updateColor(value) {
		ambientLight.color.setRGB(lightParams.r / 255, lightParams.g / 255, lightParams.b / 255);
		}

	}
	{
		const color = 0xFFFFFF;
		const intensity = 2.5;
		const light = new THREE.DirectionalLight( color, intensity );
		light.position.set( 5, 10, 2 );
		scene.add( light );
		scene.add( light.target );
	}

	function frameArea( sizeToFitOnScreen, boxSize, boxCenter, camera ) {

		const halfSizeToFitOnScreen = sizeToFitOnScreen * 0.5;
		const halfFovY = THREE.MathUtils.degToRad( camera.fov * .5 );
		const distance = halfSizeToFitOnScreen / Math.tan( halfFovY );
		// compute a unit vector that points in the direction the camera is now
		// in the xz plane from the center of the box
		const direction = ( new THREE.Vector3() )
			.subVectors( camera.position, boxCenter )
			.multiply( new THREE.Vector3( 1, 0, 1 ) )
			.normalize();

		// move the camera to a position distance units way from the center
		// in whatever direction the camera was from the center already
		camera.position.copy( direction.multiplyScalar( distance ).add( boxCenter ) );

		// pick some near and far values for the frustum that
		// will contain the box.
		camera.near = boxSize / 100;
		camera.far = boxSize * 100;

		camera.updateProjectionMatrix();

		// point the camera to look at the center of the box
		camera.lookAt( boxCenter.x, boxCenter.y, boxCenter.z );

	}

	{

		const gltfLoader = new GLTFLoader();
		gltfLoader.load( './model_store/gltf_origin/untitled2.gltf', ( gltf ) => {//./model_store/gltf_withCameraAnimation/camera_on.gltf
			// if (gltf.cameras && gltf.cameras.length > 0) {
			// 	cameras.push(gltf.cameras[0]);
			// }
			mixer = new THREE.AnimationMixer(gltf.scene);
			gltf.animations.forEach((clip) => {
				// 在这里，你可以匹配clip.name来决定它是哪个模型的动画
					const action = mixer.clipAction(clip);
					action.play();
			});
			gltf.scene.traverse((object)=>{
				if(object.isMesh&&object.material){
					if(object.name!='Plane015'&&object.name!='Plane'){
						object.material.transparent = true;
						object.material.opacity = 0.75;
					}
					else if(object.name=='Plane'){
						// object.material.transparent = true;
						// object.material.opacity = 0.5;
					}
					else{
						object.material.transparent = true;
						object.material.opacity = 0.5;
					}				
				}
			})
			const root = gltf.scene;
			scene.add( root );

			// compute the box that contains all the stuff
			// from root and below
			const box = new THREE.Box3().setFromObject( root );

			const boxSize = box.getSize( new THREE.Vector3() ).length();
			const boxCenter = box.getCenter( new THREE.Vector3() );

			// set the camera to frame the box
			frameArea( boxSize * 0.5, boxSize, boxCenter, cameras[0] );
			//frameArea( boxSize * 0.5, boxSize, boxCenter, cameras[1] );
			

			// update the Trackball controls to handle the new size
			controls.maxDistance = boxSize * 10;
			controls.target.copy( boxCenter );
			controls.update();

		} );

	}

	function resizeRendererToDisplaySize( renderer ) {

		const canvas = renderer.domElement;
		const width = canvas.clientWidth;
		const height = canvas.clientHeight;
		const needResize = canvas.width !== width || canvas.height !== height;
		if ( needResize ) {
			renderer.setSize( width, height, false );
		}
		return needResize;
	}
	var i = 0;
	function render() {
		requestAnimationFrame( render );
		if ( resizeRendererToDisplaySize( renderer ) ) {

			const canvas = renderer.domElement;
			cameras[0].aspect = canvas.clientWidth / canvas.clientHeight;
			cameras[0].updateProjectionMatrix();
			camera.aspect = canvas.clientWidth / canvas.clientHeight;
			camera.updateProjectionMatrix();
	     }
		if (i < points.length) {
			// 相机位置设置在当前点位置
			camera.position.set(points[i].x, points[i].y, points[i].z);
			// 设置相机观察点为当前点的下一个点，两点可以构成一个视线方向
			// 你可以简单理解为：要始终保持视线为曲线的切线方向
			// camera.lookAt(new THREE.Vector3(points[i + 1].x, points[i + 1].y, points[i + 1].z));
			i += 1
    	} 
		const frameT = clock.getDelta();
		mixer.update(frameT);
		renderer.render(scene,camera);
	}
	//render();
	requestAnimationFrame(render);

}
main();
</script>
</body></html>
